
/*----------------------------------------------------------------------------------------------*\
cbb_stack # (
    .DATA_DEPTH ( statck_size),
    .DATA_WIDTH ( 10),
    .ADDR_WIDTH ( 5) 
) u_cbb_stack (
    .clk    (clk), // 输入时钟信号
    .reset  (reset), // 输入复位信号
    .push   ()), // 入栈信号
    .pop    (), 
    .i_data (), 
    .o_data () // 输出栈顶信号
);
\*----------------------------------------------------------------------------------------------*/


module cbb_stack #(
    parameter DATA_DEPTH = 8,
    parameter DATA_WIDTH = 8,
    parameter ADDR_WIDTH = 5 
)
(
    input clk, // 输入时钟信号
    input reset, // 输入复位信号
    input push, // 入栈信号
    input pop , 
    input [DATA_WIDTH - 1 : 0 ] i_data , 
    output [DATA_WIDTH - 1 :0] o_data // 输出栈顶信号
);


reg [ADDR_WIDTH -1 : 0 ] top ;
wire [ADDR_WIDTH -1 : 0 ] address ; 
assign address = top + push - pop;

reg [ DATA_WIDTH - 1 : 0 ] data_a ;
reg wren_a ;
always@(posedge clk) begin
    if(reset) begin 
        top <= {(ADDR_WIDTH){1'b1}}  ;
        data_a <= {(DATA_WIDTH){1'b0}} ;
        wren_a <= 1'b0;
    end else begin
        wren_a <= 1'b0;

        if(push) begin
            top <=  top + 1'b1;
            data_a <= i_data;
            wren_a <= 1'b1;
        end 
        else if( pop ) begin
            top <=  top - 1'b1  ;
        end
    end
end

cbb_dpram_2 #(
    .DATA_DEPTH    ( DATA_DEPTH ) ,  // 数据深度 ， 存的数据个数
    .DATA_WIDTH    ( DATA_WIDTH    ),  // 数据位宽
    .ADDR_WIDTH    ( ADDR_WIDTH    ),  // 地址位宽
    .ENABLE_ASYNC  ( 0    )   // 是否设置输出异步 1：EDA会使用逻辑单元模拟  0: eda大概率会调用memory
) u_cbb_dpram (
	.address_a ( address) ,
	.address_b ( top) ,
	.clock     ( clk) ,
	.data_a    ( data_a) ,
	.data_b    ( 10'D0) ,
	.wren_a    ( wren_a) ,  // 高电平时写数据
	.wren_b    ( 1'b0) ,
	.q_a       ( ) ,
	.q_b       ( o_data) 
) ;

endmodule
